#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include "dominion.h"
#include "dominion_helpers.h"
#include "rngs.h"
#include "testutils.h"

void initializeGame_test()
{
  int i, j, k, pass, numPlayers, k[10], seedIterator;
  int seeds[7] = {-2, -1, 0, 1, 2147483646, 2147483647, 2147483648};
  struct gameState *state;
  struct gameState blankState = {0};

  numPlayers = 1;
  seedIterator = 0;

  for(i = 0; i < MAX_ITERATIONS; i++){
    
    printf("number of players: %d\n", numPlayers);
    printf("seed: %d\n", seeds[seedIterator]);

    // set Kingdom cards
    for(j = 0; j < 10; j++){
      k[j] = random_kcard();
      // unique k cards for every other test
      while(j > 0 && (i % 2 == 1) && (k[j - 1] == k[j]))
	k[j] = random_kcard();
      printf("k[%d] = %d\n", j, k[j]);
    }


    if(initializeGame(numPlayers, k, seeds[seedsIterator], &state) == -1){
      if(numPlayers < 1 || numPlayers > 4)
	pass++;
      
      if(seedIterator == 6)
	pass++;
    
    } else {
      
      if(numPlayers < 1 || numPlayers > 4)
	printf("Failure, function returned successfully with incorrect # of players\n");
      
      if(seedIterator == 6)
	printf("Failure, function returned successfully with out-of-range seed\n");
      
      // check number of players
      if(state.numPlayers == numPlayers)
	pass++;
      else
	printf("Failure, numPlayers not set correctly\n");

      // check victory card supply
      if(numPlayers == 2){
	if(state.supplyCount[estate] == 8)
	  pass++;
	else
	  printf("Failure, estate not properly set\n");

	if(state.supplyCount[duchy] == 8)
	  pass++;
	else
	  printf("Failure, duchy not properly set\n");

	if(state.supplyCount[province] == 8)
          pass++;
        else
          printf("Failure, province not properly set\n");
      }
      if(numPlayers > 2 && numPlayers < 5){
	if(state.supplyCount[estate] == 12)
	  pass++;
	else
	  printf("Failure, estate not properly set\n");
	
	if(state.supplyCount[duchy] == 12)
	  pass++;
	else
	  printf("Failure, duchy not properly set\n");
	
	if(state.supplyCount[province] == 12)
	  pass++;
	else
	  printf("Failure, province not properly set\n");	
      }
    
      // check kingdom card supplies
      for(j = 0; j < 10; j++){
	if(state.kingdomCards[j] == great_hall || state.kingdomCards[j] == gardens){
	  if(numPlayers == 2){
	    if(state.supplyCount[j] == 8)
	      pass++;
	    else
	      printf("supply [%d] not properly set to 8\n", supplyCount[j]);
	  } else {
	    if(state.supplyCount[j] == 12)
	      pass++;
	    else
	      printf("supply [%d] not properly set to 12\n", supplyCount[j]);
	  }
	} else {
	  if(state.supplyCount[j] == 10)
	    pass++;
	  else
	    printf("supply [%d] not properly set to 10\n", supplyCount[j]);
	}
      }

      // check treasure card supply
      if(state.supplyCount[copper] == 60 - (7 * numPlayers))
	pass++;
      else
	printf("copper not set properly\n");
      if(state.supplyCount[silver] == 40)
	pass++;
      else
	printf("silver not set properly\n");
      if(state.supplyCount[gold] == 30)
	pass+;
      else
	printf("Gold not set properly\n");
      
      // check player decks
      for(j = 0; j < numPlayers; j++){
        if(state.deckCount[j] == 10)
	  pass++;
	else
	  printf("deckCount not properly set to 10\n");

	if(card_count(state.deck[j], estate, state.deckCount[j]) == 3)
	  pass++;
	else
	  printf("wrong # of estate cards in player %d's deck\n", j + 1);

	if(card_count(state.deck[j], copper, state.deckCount[j]) == 7)
          pass++;
        else
          printf("wrong # of copper cards in player %d's deck\n", j + 1);
	
	if(state.discardCount[j] == 0)
	  pass++;
	else
	  printf("discardCount not set to 0 for player %d\n", j + 1);
      }
      
      if(state.outpostPlayed == 0)
	pass++;
      else
	printf("outpostPlayed not set to 0\n");

      if(state.phase == 0)
	pass++;
      else
	printf("phase not set to 0\n");

      if(state.numActions == 1)
	pass++;
      else
	printf("numActions not set to 1\n");
      
      if(state.numBuys == 1)
	pass++;
      else
	printf("numBuys not set to 1\n");

      if(state.playedCardCount == 0)
	pass++;
      else
	printf("playedCardCount not set to 0\n");
      
      if(state.whoseTurn == 0)
	pass++;
      else
	printf("whoseTurn not set to 0\n");

      if(state.handCount[0] == 0)
	pass++;
      else
	printf("handCount[0] not set to 0\n");	    
    }
    
    // reset structure every 4th iteration
    if(i % 4 == 0)
      state = blankState;
    
    // cycle through possible number of players for each iteration
    if(numPlayers == 5)
      numPlayers = 1;
    else
      numPlayers++;

    // cycle through seeds
    if(seedsIterator == 6)
      seedsIterator = 0;
    else
      seedsIterator++;
  }
}

int main()
{
  initializeGame_test();
  return 0;
}
